package com.yarolegovich.lovelydialog;

import ohos.agp.components.Component;
import ohos.agp.components.DirectionalLayout;
import ohos.agp.components.Image;
import ohos.agp.components.LayoutScatter;
import ohos.agp.components.Text;
import ohos.agp.utils.Color;
import ohos.agp.window.dialog.BaseDialog;
import ohos.agp.window.dialog.CommonDialog;
import ohos.app.Context;
import ohos.media.image.PixelMap;
import ohos.utils.PacMap;

/**
 * Created by yarolegovich on 16.04.2016.
 */
@SuppressWarnings({"unchecked", "WeakerAccess"})
public abstract class AbsLovelyDialog<T extends AbsLovelyDialog> {
    private static final String KEY_SAVED_STATE_TOKEN = "key_saved_state_token";
    private CommonDialog dialog;
    private Component dialogView;
    private Image iconView;
    private Text topTitleView;
    private Text titleView;
    private Text messageView;
    private Context context;

    public AbsLovelyDialog(Context context) {
        this(context, 0);
    }

    public AbsLovelyDialog(Context context, int theme) {
        this(context, theme, 0);
    }

    public AbsLovelyDialog(Context context, int theme, int layoutRes) {
        this.context = context;
        if (layoutRes == 0) {
            layoutRes = getLayout();
        }
        init(new CommonDialog(context), layoutRes);
    }

    private void init(CommonDialog commonDialog, int res) {
        dialogView = LayoutScatter.getInstance(context).parse(res, null, true);
        dialog = commonDialog.setContentCustomComponent(dialogView);
        dialog.setDialogListener(new BaseDialog.DialogListener() {
            @Override
            public boolean isTouchOutside() {
                if (AbsLovelyDialog.this instanceof LovelyProgressDialog) {
                    ((CircleRingComponent) findView(ResourceTable.Id_progress)).stopAnim();
                }
                dialog.destroy();
                return false;
            }
        });
        dialog.setSize(ResUtil.getScreenWidth(context) * 4 / 5, DirectionalLayout.LayoutConfig.MATCH_CONTENT);
        dialog.setTransparent(false);
        DirectionalLayout viewTop = (DirectionalLayout) dialogView.findComponentById(ResourceTable.Id_view_top);
        DirectionalLayout topLayout = (DirectionalLayout) LayoutScatter.getInstance(context).parse(ResourceTable.Layout_view_color_area, null, false);
        viewTop.addComponent(topLayout);
        iconView = (Image) topLayout.findComponentById(ResourceTable.Id_top_icon);
        topTitleView = (Text) topLayout.findComponentById(ResourceTable.Id_top_title);
        DirectionalLayout viewMessage = (DirectionalLayout) dialogView.findComponentById(ResourceTable.Id_view_message);
        DirectionalLayout messageLayout = (DirectionalLayout) LayoutScatter.getInstance(context).parse(ResourceTable.Layout_view_title_and_message, null, false);
        viewMessage.addComponent(messageLayout);
        titleView = (Text) messageLayout.findComponentById(ResourceTable.Id_title);
        messageView = (Text) messageLayout.findComponentById(ResourceTable.Id_message);
    }

    protected abstract int getLayout();

    public T setMessage(int message) {
        return setMessage(string(message));
    }

    public T setMessage(CharSequence message) {
        messageView.setVisibility(Component.VISIBLE);
        messageView.setText(message.toString());
        return (T) this;
    }

    public T setTitle(int title) {
        return setTitle(string(title));
    }

    public T setTopTitle(int title) {
        return setTopTitle(string(title));
    }

    public T setTitle(CharSequence title) {
        titleView.setVisibility(Component.VISIBLE);
        titleView.setText(title.toString());
        return (T) this;
    }

    public T setTopTitle(CharSequence title) {
        topTitleView.setVisibility(Component.VISIBLE);
        topTitleView.setText(title.toString());
        return (T) this;
    }

    public T setTopTitleColor(int color) {
        topTitleView.setTextColor(new Color(color));
        return (T) this;
    }

    public T setIcon(PixelMap bitmap) {
        iconView.setVisibility(Component.VISIBLE);
        iconView.setPixelMap(bitmap);
        return (T) this;
    }

    public T setIcon(int iconRes) {
        iconView.setVisibility(Component.VISIBLE);
        iconView.setPixelMap(iconRes);
        return (T) this;
    }

    public T setTitleGravity(int gravity) {
        titleView.setTextAlignment(gravity);
        return (T) this;
    }

    public T setMessageGravity(int gravity) {
        messageView.setTextAlignment(gravity);
        return (T) this;
    }

    public T setTopColor(int topColor) {
        findView(ResourceTable.Id_color_area).setBackground(ResUtil.getShapeElement6(topColor));
        return (T) this;
    }

    public T setTopColorRes(int topColoRes) {
        return setTopColor(color(topColoRes));
    }

    /*
     * You should call method saveInstanceState on handler object and then use saved info to restore
     * your dialog in onRestoreInstanceState. Static methods wasDialogOnScreen and getDialogId will
     * help you in this.
     */
    public T setInstanceStateHandler(int id, LovelySaveStateHandler handler) {
        handler.handleDialogStateSave(id, this);
        return (T) this;
    }

    public T setCancelable(boolean cancelable) {
        return (T) this;
    }

    public T setSavedInstanceState(PacMap savedInstanceState) {
        if (savedInstanceState != null) {
            boolean hasSavedStateHere =
                    savedInstanceState.getKeys().contains(KEY_SAVED_STATE_TOKEN) &&
                            savedInstanceState.getSerializable(KEY_SAVED_STATE_TOKEN).equals(getClass());
            if (hasSavedStateHere) {
                restoreState(savedInstanceState);
            }
        }
        return (T) this;
    }

    public CommonDialog show() {
        dialog.show();
        return dialog;
    }

    public CommonDialog create() {
        return dialog;
    }

    public void dismiss() {
        dialog.destroy();
    }

    void onSaveInstanceState(PacMap outState) {
        outState.putSerializableObject(KEY_SAVED_STATE_TOKEN, getClass());
    }

    void restoreState(PacMap savedState) {
    }

    public boolean isShowing() {
        return dialog != null && dialog.isShowing();
    }

    protected String string(int res) {
        return ResUtil.getString(context, res);
    }

    protected int color(int colorRes) {
        return ResUtil.getColor(context, colorRes);
    }

    protected Context getContext() {
        return dialogView.getContext();
    }

    protected <ViewClass extends Component> ViewClass findView(int id) {
        return (ViewClass) dialogView.findComponentById(id);
    }

    protected class ClickListenerDecorator implements Component.ClickedListener {
        private Component.ClickedListener clickListener;
        private boolean closeOnClick;
        protected ClickListenerDecorator(Component.ClickedListener clickListener, boolean closeOnClick) {
            this.clickListener = clickListener;
            this.closeOnClick = closeOnClick;
        }

        @Override
        public void onClick(Component component) {
            if (clickListener != null) {
                if (clickListener instanceof LovelyDialogCompat.DialogOnClickListenerAdapter) {
                    LovelyDialogCompat.DialogOnClickListenerAdapter listener =
                            (LovelyDialogCompat.DialogOnClickListenerAdapter) clickListener;
                    listener.onClick(dialog, component.getId());
                } else {
                    clickListener.onClick(component);
                }
            }
            if (closeOnClick) {
                dismiss();
            }
        }
    }
}
